package org.zcl;

import lombok.SneakyThrows;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

@SpringBootApplication
public class ZookeeperApplication {

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {

        // watch注册发生在，读类型调用，get、existes
        // new zk,watch session级别
        // 连接的服务宕机会切换另一台，sessionId不会变
        CountDownLatch countDownLatch = new CountDownLatch(1);
        ZooKeeper zk = new ZooKeeper("192.168.150.11:2181,192.168.150.12:2181,192.168.150.13:2181,192.168.150.14:2181", 3000, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                Event.KeeperState state = event.getState(); // 事件状态
                Event.EventType type = event.getType(); // 什么事件调的
                String path = event.getPath();
                System.out.println("new zk watch"+event.toString());
                switch (state) {
                    case Unknown:
                        break;
                    case Disconnected:
                        break;
                    case NoSyncConnected:
                        break;
                    case SyncConnected:
                        System.out.println("connected");
                        countDownLatch.countDown();
                        break;
                    case AuthFailed:
                        break;
                    case ConnectedReadOnly:
                        break;
                    case SaslAuthenticated:
                        break;
                    case Expired:
                        break;
                    case Closed:
                        break;
                }

                switch (type) {
                    case None:
                        break;
                    case NodeCreated:
                        break;
                    case NodeDeleted:
                        break;
                    case NodeDataChanged:
                        break;
                    case NodeChildrenChanged:
                        break;
                    case DataWatchRemoved:
                        break;
                    case ChildWatchRemoved:
                        break;
                    case PersistentWatchRemoved:
                        break;
                }
            }
        });
        countDownLatch.await();
        ZooKeeper.States state = zk.getState();
        switch (state) {
            case CONNECTING:
                System.out.println("ing......");
                break;
            case ASSOCIATING:
                break;
            case CONNECTED:
                System.out.println("ed......");
                break;
            case CONNECTEDREADONLY:
                break;
            case CLOSED:
                break;
            case AUTH_FAILED:
                break;
            case NOT_CONNECTED:
                break;
        }

        String pathName = zk.create("/ooxx", "oldData".getBytes(StandardCharsets.UTF_8), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
        System.out.println(pathName);
        Stat stat = new Stat();
        // 一个watch监控一次事件
        byte[] node = zk.getData("/ooxx", new Watcher() {
            @SneakyThrows
            @Override
            public void process(WatchedEvent event) {
                System.out.println("getData watch" + event.toString());
                // 继续监控,true default watch,this current watch
                zk.getData("/ooxx", this, stat);
            }
        }, stat);

        System.out.println(new String(node));
        // 触发get回调
        Stat stat1 = zk.setData("/ooxx", "newData".getBytes(StandardCharsets.UTF_8), 0);
        // 不会触发get回调
        Stat stat2 = zk.setData("/ooxx", "newData01".getBytes(StandardCharsets.UTF_8), stat1.getVersion());


        // get到结果后回调，ctx可任意对象例如：abc
        System.out.println("-------async start------");
        zk.getData("/ooxx", false, new AsyncCallback.DataCallback() {
            @Override
            public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {
                // 异步获取，减少等待
                System.out.println("------async call back------");
                System.out.println(ctx.toString());
                System.out.println(new String(data));
            }
        }, "abc");
        System.out.println("------async over------");
        TimeUnit.SECONDS.sleep(222222);

    }

}
